package com.letv.core.network.volley;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.ProtocolVersion;
import org.apache.http.StatusLine;
import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.message.BasicStatusLine;

import android.text.TextUtils;

import com.letv.core.network.volley.VolleyRequest.HttpRequestMethod;
import com.letv.core.network.volley.listener.HttpStack;
import com.letv.core.utils.LetvUtils;

/**
 * HttpUrlConnection方式执行请求
 * 
 * @author zhuqiao
 * 
 */
public class HurlStack implements HttpStack {

    @Override
    public HttpResponse performRequest(VolleyRequest<?> request) {
        String url = request.getUrl();
        if (TextUtils.isEmpty(url)) {
            return null;
        }

        HttpURLConnection connection = null;

        try {
            URL parsedUrl = new URL(url);
            connection = openConnection(parsedUrl, request);

            // 添加头信息
            Map<String, String> headers = request.mHeadMap;
            if (headers != null && headers.size() > 0) {
                for (String headerName : headers.keySet()) {
                    connection.addRequestProperty(headerName, headers.get(headerName));
                }
            }

            String ua = LetvUtils.getUa();
            if (!TextUtils.isEmpty(ua)) {
                connection.addRequestProperty("User-agent", ua);
            }

            setConnectionParametersForRequest(connection, request);

            int responseCode = connection.getResponseCode();
            if (responseCode == -1) {
                // no valid response code
                return null;
            }

            StatusLine responseStatus = new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1),
                    connection.getResponseCode(), connection.getResponseMessage());
            BasicHttpResponse response = new BasicHttpResponse(responseStatus);
            response.setEntity(entityFromConnection(connection));
            for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
                if (header.getKey() != null) {
                    Header h = new BasicHeader(header.getKey(), header.getValue().get(0));
                    response.addHeader(h);
                }
            }

            return response;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }

        return null;
    }

    private HttpURLConnection openConnection(URL url, VolleyRequest<?> request) throws Exception {
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        int timeoutMs = request.mTimeOut;
        connection.setConnectTimeout(timeoutMs);
        connection.setReadTimeout(timeoutMs);
        connection.setUseCaches(false);
        connection.setDoInput(true);

        return connection;
    }

    /**
     * 设置连接参数
     * 
     * @param connection
     * @param request
     * @throws Exception
     */
    static void setConnectionParametersForRequest(HttpURLConnection connection, VolleyRequest<?> request)
            throws Exception {
        HttpRequestMethod method = request.mHttpRequestMethod;
        if (method == HttpRequestMethod.GET) {
            connection.setRequestMethod("GET");
        } else if (method == HttpRequestMethod.POST) {
            connection.setRequestMethod("POST");
            addBodyIfExists(connection, request, request.getPostBody());
        } else {
            // default is auto
            byte[] body = request.getPostBody();
            if (body == null) {
                connection.setRequestMethod("GET");
            } else {
                connection.setRequestMethod("POST");
                addBodyIfExists(connection, request, body);
            }
        }
    }

    /**
     * 添加post参数
     * 
     * @param connection
     * @param request
     */
    private static void addBodyIfExists(HttpURLConnection connection, VolleyRequest<?> request, byte[] body)
            throws Exception {
        if (body == null) {
            return;
        }
        connection.setDoOutput(true);
        connection.addRequestProperty(HEADER_CONTENT_TYPE, request.getBodyContentType());
        DataOutputStream out = new DataOutputStream(connection.getOutputStream());
        out.write(body);
        out.close();
    }

    static HttpEntity entityFromConnection(HttpURLConnection connection) {
        BasicHttpEntity entity = new BasicHttpEntity();
        InputStream inputStream;
        try {
            inputStream = connection.getInputStream();
        } catch (IOException e) {
            inputStream = connection.getErrorStream();
        }
        entity.setContent(inputStream);
        entity.setContentLength(connection.getContentLength());
        entity.setContentEncoding(connection.getContentEncoding());
        entity.setContentType(connection.getContentType());
        return entity;
    }
}
